package com.yami.shop.webservice.common.service.impl;

import cn.hutool.extra.mail.MailException;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yami.shop.bean.enums.PaySeviceTypeCode;
import com.yami.shop.bean.model.EntrustVo;
import com.yami.shop.bean.model.TransactionAndEntrustVo;
import com.yami.shop.bean.model.TransactionVo;
import com.yami.shop.common.bean.HSExchange;
import com.yami.shop.common.util.DateUtils;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.webservice.common.model.ClassCardVo;
import com.yami.shop.webservice.common.model.ClassVo;
import com.yami.shop.webservice.common.service.WapiSubmittedEntrustService;
import com.yami.shop.webservice.common.service.WapiSubmittedService;
import com.yami.shop.webservice.common.service.WapiSubmittedTransactionService;
import com.yami.shop.webservice.common.util.MD5Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 *
 * @author zhangchaoqun
 * @date 2021-10-13
 */
@Service
public class WapiSubmittedServiceImpl implements WapiSubmittedService
{
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ShopConfig shopConfig;

    @Autowired
    private WapiSubmittedEntrustService wapiSubmittedEntrustService;
    @Autowired
    private WapiSubmittedTransactionService wapiSubmittedTransactionService;
    @Resource
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Resource
    private TransactionDefinition transactionDefinition;
    /**
     * 成交报送
     * @param transactionVoList
     * @return
     * @throws MailException
     */
    @Override
    public void toWapiSubmittedTransaction(List<TransactionVo> transactionVoList) throws MailException {
        HSExchange hsExchange = shopConfig.getAPIExchange();
        JSONArray jsonParam = new JSONArray();
        for (TransactionVo transactionVo:transactionVoList) {
            JSONObject jo = new JSONObject();
            //必传参数
            jo.put("bizType","1");
            jo.put("dealId",transactionVo.getDealId());
            jo.put("openMemCode",transactionVo.getOpenMemCode());
            jo.put("openFundAccount",transactionVo.getOpenFundAccount());
            jo.put("openTradeAccount",transactionVo.getOpenFundAccount());
            jo.put("oppMemCode",transactionVo.getOppMemCode());
            jo.put("oppFundAccount",transactionVo.getOppFundAccount());
            jo.put("oppTradeAccount",transactionVo.getOppFundAccount());
            jo.put("productCode",transactionVo.getProductCode());
            jo.put("tradeDir","1");
            jo.put("dealType","1");
            jo.put("oppDealType","2");
            jo.put("tradeType","1");
            jo.put("dealPrice",transactionVo.getDealPrice());
            jo.put("dealQuantity",transactionVo.getDealQuantity());
            jo.put("dealTotalPrice",transactionVo.getDealTotalPrice());
            jo.put("dealTime", DateUtils.dateToStrHmsTwo(new Date()));
            jo.put("depotOrderNo","0");
            jo.put("oppDepotOrderNo","0");
            jo.put("orderId",transactionVo.getOrderId());
            jo.put("oppOrderId",transactionVo.getOppOrderId());
            jo.put("settlementDate",DateUtils.dateToStrYmdTwo(new Date()));
//            jo.put("depositRatioType","0");
            //非必须参数
//            jo.put("project_list_code",null);
//            jo.put("hold_price",null);
//            jo.put("deposit_rate",null);
//            jo.put("deposit_type",null);
//            jo.put("deposit_balance",null);
//            jo.put("opp_deposit_ratio_type",null);
//            jo.put("opp_deposit_rate",null);
//            jo.put("opp_deposit_balance",null);
            jsonParam.add(jo);
        }
        //获取请求内容
        JSONObject biz_content = new JSONObject();
        biz_content.put("fileType","01");
        biz_content.put("jsonParam",jsonParam);
        //基础参数
        Map<String, Object> orgParam = new HashMap<>();
        orgParam.put("version", "v1");
        orgParam.put("app_id",hsExchange.getAppId());
        orgParam.put("charset","UTF-8");
        orgParam.put("timestamp", DateUtils.dateToStrYmdTwo(new Date()));
        orgParam.put("biz_content",biz_content);
        //获取sign
        orgParam.put("sign", MD5Utils.md5Two("UTF-8",biz_content.toString(),hsExchange.getAppSecret()));
        StringBuilder targetUrl = new StringBuilder();
        for (Map.Entry<String, Object> entry : orgParam.entrySet()) {
            targetUrl.append(entry.getKey()).append("=").append( entry.getValue()).append("&");
        }
        String param = targetUrl.substring(0, (targetUrl.length() - 1)).toString();
        // 组装外层通用参数 发起审核通知
        log.info("成交报送地址"+hsExchange.getAppUrl()+"/mallcloud-webservice/openapi/"+ PaySeviceTypeCode.function_id12);
        log.info("成交报送参数"+param);
        String result = HttpRequest.post(hsExchange.getAppUrl()+"/mallcloud-webservice/openapi/"+PaySeviceTypeCode.function_id12).body(param).setConnectionTimeout(60000).execute().body();
        log.info("成交报送返回结果"+result);
        JSONObject jsonObject =  JSON.parseObject(result);
        if (null != jsonObject) {
            if (0 == jsonObject.getInteger("error_code") && null != jsonObject.getJSONObject("rsp_content")) {
                JSONObject res = jsonObject.getJSONObject("rsp_content");
                if(!"0000".equals(res.getString("errorNo"))){
                    throw  new MailException(res.getString("errorInfo"));
                }
            }else {
                log.error(jsonObject.getString("error_msg"));
                throw new MailException(jsonObject.getString("error_msg"));
            }
        }else {
            log.error("成交报送返回空异常");
            throw new MailException("成交报送接口返回空");
        }
    }
    /**
     * 委托报送
     * @param entrustVoList
     * @return
     * @throws MailException
     */
    @Override
    public void toWapiSubmittedEntrust(List<EntrustVo> entrustVoList) throws MailException {
        HSExchange hsExchange = shopConfig.getAPIExchange();
        JSONArray jsonParam = new JSONArray();
        for (EntrustVo entrustVo:entrustVoList) {
            JSONObject jo = new JSONObject();
            //必传参数
            jo.put("entrustNo",entrustVo.getEntrustNo());
            jo.put("productCode",entrustVo.getProductCode());
            jo.put("memCode",entrustVo.getMemCode());
            jo.put("tradeDir",entrustVo.getTradeDir());
            jo.put("orderType","1");
            jo.put("orderWay","1");
            jo.put("depositWay","1");
            jo.put("orderPrice",entrustVo.getOrderPrice());
            jo.put("orderQuantity",entrustVo.getOrderQuantity());
            jo.put("leftQuantity","0");
            jo.put("poundageRatioType","1");
            jo.put("validDate",DateUtils.dateToStrYmdTwo(new Date()));
            jo.put("trader",entrustVo.getMemCode()+"000");
            jo.put("orderTime",DateUtils.dateToStrYmdHmsTwo(entrustVo.getOrderTime()));
            jo.put("orderIp","127.0.0.1");
            jo.put("orderStatus","3");
            jo.put("busiDatetime",DateUtils.dateToStrYmdHmsTwo(new Date()));
            //非必须参数
//            jo.put("project_list_code",null);
//            jo.put("order_serial_no",null);
//            jo.put("deposit_rate",null);
//            jo.put("deposit_ratio_type",null);
//            jo.put("deposit_type",null);
//            jo.put("poundage_rate",null);
//            jo.put("trade_poundage",null);
//            jo.put("paper_balance",null);
//            jo.put("order_frozen",null);
//            jo.put("tax_rate",null);
//            jo.put("remark",null);
            jsonParam.add(jo);
        }
        //获取请求内容
        JSONObject biz_content = new JSONObject();
        biz_content.put("fileType","09");
        biz_content.put("jsonParam",jsonParam);
        //基础参数
        Map<String, Object> orgParam = new HashMap<>();
        orgParam.put("version", "v1");
        orgParam.put("app_id",hsExchange.getAppId());
        orgParam.put("charset","UTF-8");
        orgParam.put("timestamp", DateUtils.dateToStrYmdTwo(new Date()));
        orgParam.put("biz_content",biz_content);
        //获取sign
        orgParam.put("sign", MD5Utils.md5Two("UTF-8",biz_content.toString(),hsExchange.getAppSecret()));
        StringBuilder targetUrl = new StringBuilder();
        for (Map.Entry<String, Object> entry : orgParam.entrySet()) {
            targetUrl.append(entry.getKey()).append("=").append( entry.getValue()).append("&");
        }
        String param = targetUrl.substring(0, (targetUrl.length() - 1)).toString();
        // 组装外层通用参数 发起审核通知
        log.info("委托报送地址"+hsExchange.getAppUrl()+"/mallcloud-webservice/openapi/"+ PaySeviceTypeCode.function_id12);
        log.info("委托报送参数"+param);
        String result = HttpRequest.post(hsExchange.getAppUrl()+"/mallcloud-webservice/openapi/"+PaySeviceTypeCode.function_id12).body(param).setConnectionTimeout(60000).execute().body();
        log.info("委托报送返回结果"+result);
        JSONObject jsonObject =  JSON.parseObject(result);
        if (null != jsonObject) {
            if (0 == jsonObject.getInteger("error_code") && null != jsonObject.getJSONObject("rsp_content")) {
                JSONObject res = jsonObject.getJSONObject("rsp_content");
                if(!"0000".equals(res.getString("errorNo"))){
                    throw  new MailException(res.getString("errorInfo"));
                }
            }else {
                log.error(jsonObject.getString("error_msg"));
                throw new MailException(jsonObject.getString("error_msg"));
            }
        }else {
            log.error("委托报送返回空异常");
            throw new MailException("委托报送接口返回空");
        }
    }
    /**
     * 商品种类报送
     * @param classVoList
     * @return
     * @throws MailException
     */
    @Override
    public void toWapiSubmittedGoodClass(List<ClassVo> classVoList) throws MailException {
        HSExchange hsExchange = shopConfig.getAPIExchange();
        JSONArray jsonParam = new JSONArray();
        for (ClassVo classVo:classVoList) {
            JSONObject jo = new JSONObject();
            //必传参数
            jo.put("productName",classVo.getProductName());
            jo.put("productCode",classVo.getProductCode());
            //非必须参数
//            jo.put("remark",null);
            jsonParam.add(jo);
        }
        //获取请求内容
        JSONObject biz_content = new JSONObject();
        biz_content.put("fileType","14");
        biz_content.put("jsonParam",jsonParam);
        //基础参数
        Map<String, Object> orgParam = new HashMap<>();
        orgParam.put("version", "v1");
        orgParam.put("app_id",hsExchange.getAppId());
        orgParam.put("charset","UTF-8");
        orgParam.put("timestamp", DateUtils.dateToStrYmdTwo(new Date()));
        orgParam.put("biz_content",biz_content);
        //获取sign
        orgParam.put("sign", MD5Utils.md5Two("UTF-8",biz_content.toString(),hsExchange.getAppSecret()));
        StringBuilder targetUrl = new StringBuilder();
        for (Map.Entry<String, Object> entry : orgParam.entrySet()) {
            targetUrl.append(entry.getKey()).append("=").append( entry.getValue()).append("&");
        }
        String param = targetUrl.substring(0, (targetUrl.length() - 1)).toString();
        // 组装外层通用参数 发起审核通知
        log.info("种类报送地址"+hsExchange.getAppUrl()+"/mallcloud-webservice/openapi/"+ PaySeviceTypeCode.function_id12);
        log.info("种类报送参数"+param);
        String result = HttpRequest.post(hsExchange.getAppUrl()+"/mallcloud-webservice/openapi/"+PaySeviceTypeCode.function_id12).body(param).setConnectionTimeout(60000).execute().body();
        log.info("种类报送返回结果"+result);
        JSONObject jsonObject =  JSON.parseObject(result);
        if (null != jsonObject) {
            if (0 == jsonObject.getInteger("error_code") && null != jsonObject.getJSONObject("rsp_content")) {
                JSONObject res = jsonObject.getJSONObject("rsp_content");
                if(!"0000".equals(res.getString("errorNo"))){
                    throw  new MailException(res.getString("errorInfo"));
                }
            }else {
                log.error(jsonObject.getString("error_msg"));
                throw new MailException(jsonObject.getString("error_msg"));
            }
        }else {
            log.error("种类报送返回空异常");
            throw new MailException("种类报送接口返回空");
        }
    }
    /**
     * 交收卡种类报送
     * @param classVoList
     * @return
     * @throws MailException
     */
    @Override
    public void toWapiSubmittedCardClass(List<ClassCardVo> classVoList) throws MailException {
        HSExchange hsExchange = shopConfig.getAPIExchange();
        JSONArray jsonParam = new JSONArray();
        for (ClassCardVo classCardVo:classVoList) {
            JSONObject jo = new JSONObject();
            //必传参数
            jo.put("mallCode",classCardVo.getMallCode());
            jo.put("mallName",classCardVo.getMallName());
            jo.put("storeCode",classCardVo.getStoreCode());
            jo.put("storeName",classCardVo.getStoreName());
            jo.put("varietyCode",classCardVo.getVarietyCode());
            jo.put("varietyName",classCardVo.getVarietyName());
            //非必须参数
//            jo.put("remark",null);
            jsonParam.add(jo);
        }
        //获取请求内容
        JSONObject biz_content = new JSONObject();
        biz_content.put("fileType","15");
        biz_content.put("jsonParam",jsonParam);
        //基础参数
        Map<String, Object> orgParam = new HashMap<>();
        orgParam.put("version", "v1");
        orgParam.put("app_id",hsExchange.getAppId());
        orgParam.put("charset","UTF-8");
        orgParam.put("timestamp",  DateUtils.dateToStrYmdTwo(new Date()));
        orgParam.put("biz_content",biz_content);
        //获取sign
        orgParam.put("sign", MD5Utils.md5Two("UTF-8",biz_content.toString(),hsExchange.getAppSecret()));
        StringBuilder targetUrl = new StringBuilder();
        for (Map.Entry<String, Object> entry : orgParam.entrySet()) {
            targetUrl.append(entry.getKey()).append("=").append( entry.getValue()).append("&");
        }
        String param = targetUrl.substring(0, (targetUrl.length() - 1)).toString();
        // 组装外层通用参数 发起审核通知
        log.info("种类报送地址"+hsExchange.getAppUrl()+"/mallcloud-webservice/openapi/"+ PaySeviceTypeCode.function_id12);
        log.info("种类报送参数"+param);
        String result = HttpRequest.post(hsExchange.getAppUrl()+"/mallcloud-webservice/openapi/"+ PaySeviceTypeCode.function_id12).body(param).setConnectionTimeout(60000).execute().body();
        log.info("种类报送返回结果"+result);
        JSONObject jsonObject =  JSON.parseObject(result);
        if (null != jsonObject) {
            if (0 == jsonObject.getInteger("error_code") && null != jsonObject.getJSONObject("rsp_content")) {
                JSONObject res = jsonObject.getJSONObject("rsp_content");
                if(!"0000".equals(res.getString("errorNo"))){
                    throw  new MailException(res.getString("errorInfo"));
                }
            }else {
                log.error(jsonObject.getString("error_msg"));
                throw new MailException(jsonObject.getString("error_msg"));
            }
        }else {
            log.error("种类报送返回空异常");
            throw new MailException("种类报送接口返回空");
        }
    }
    @Override
    public void submittedTransaction(TransactionAndEntrustVo transactionAndEntrustVo) throws MailException {
        //事务开启
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try{
            //委托报送
            toWapiSubmittedEntrust(transactionAndEntrustVo.getEntrustVoList());
            //保存委托报送记录
            wapiSubmittedEntrustService.insertEntrustVoList(transactionAndEntrustVo.getEntrustVoList());
            //手动提交事务
            dataSourceTransactionManager.commit(transactionStatus);
        }catch (Exception e){
            //手动回滚事务
            dataSourceTransactionManager.rollback(transactionStatus);
        }
        //事务开启
        TransactionStatus transactionStatus1 = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try{
            //成交报送
            toWapiSubmittedTransaction(transactionAndEntrustVo.getTransactionVoList());
            //保存成交报送记录
            wapiSubmittedTransactionService.insertTransactionVoList(transactionAndEntrustVo.getTransactionVoList());
            //手动提交事务
            dataSourceTransactionManager.commit(transactionStatus1);
        }catch (Exception e){
            //手动回滚事务
            dataSourceTransactionManager.rollback(transactionStatus1);
        }
    }
}
